home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xsok-1.000 / xsok-1 / xsok-1.01 / src / parse.c < prev    next >
C/C++ Source or Header  |  1994-11-24  |  8KB  |  277 lines

  1. /*****************************************************************************/
  2. /*                                         */
  3. /*                                         */
  4. /*    Xsok version 1.00 -- module parse.c                     */
  5. /*                                         */
  6. /*    Parsing of the level subset definition files and level files.         */
  7. /*    Written by Michael Bischoff (mbi@mo.math.nat.tu-bs.de)             */
  8. /*    November-1994                                 */
  9. /*    see COPYRIGHT.xsok for Copyright details                 */
  10. /*                                         */
  11. /*                                         */
  12. /*****************************************************************************/
  13. #ifndef _POSIX_SOURCE
  14. #define _POSIX_SOURCE
  15. #endif
  16. #include "xsok.h"
  17.  
  18. #define MAXABBREVS 32
  19. static char abbrevs[MAXABBREVS][4];
  20. static int numabbrevs;
  21.  
  22. int nwalls, nobjects, ninstances;
  23. int pushcost, movecost;
  24. const char *xsokdir;
  25. struct objects objects[MAXOBJECTS];
  26. struct walls walls[MAXWALLS];    /* wall types */
  27. struct game game;
  28. struct walls *map[MAXROW][MAXCOL];
  29. struct objects *obj[MAXROW][MAXCOL];
  30. struct objects instance[MAXINSTANCES];
  31.  
  32. static struct game init = { 1, 1, -1, -1, 0, 0, 0 };
  33. static struct walls the_void = { '\0', 16, 0,0,0,0 };
  34.  
  35. static struct walls   *omap[MAXROW][MAXCOL];
  36. static struct objects *oobj[MAXROW][MAXCOL];
  37. static struct objects oinstance[MAXINSTANCES];
  38. static struct game    ogame;
  39.  
  40. /* restore the game state for initial tableau. No graphics update */
  41. void OrgLevel(void) {
  42.     memcpy(map, omap, sizeof(map));
  43.     memcpy(obj, oobj, sizeof(obj));
  44.     memcpy(instance, oinstance, sizeof(instance));
  45.     ogame.macroStart = game.macroStart;
  46.     ogame.macroEnd   = game.macroEnd;
  47.     ogame.macro_x    = game.macro_x;
  48.     ogame.macro_y    = game.macro_y;
  49.     ogame.bookmark = game.bookmark;
  50.     ogame.stored_moves = game.stored_moves;
  51.     game = ogame;
  52. }
  53.  
  54. int maxlevel;
  55. char levelcomment[100];
  56. char levelauthor[100];
  57. static int piped;
  58.  
  59. /* open the level database and read, starting at a given line */
  60. static FILE *def_open(const char *firstline) {
  61.     FILE *fp;
  62.     char s[MAXXSOKDIRLEN+14];
  63.     char shorttype[8];
  64.     strcpy(shorttype, game.type);
  65.     shorttype[7] = '\0';
  66.  
  67.     sprintf(s, "%s/%s.def", xsokdir, shorttype);
  68.     if (!(fp = fopen(s, "r"))) {
  69.     if (!(fp = zreadopen(s)))    /* uncompress on-the-fly */
  70.         fatal("Cannot open definition file for %s\n", game.type);
  71.     piped = 1;
  72.     }
  73.     while (fgets(s, sizeof(s), fp))
  74.     if (!strcmp(s, firstline))
  75.         return fp;
  76.     fatal("No matching line found\n");
  77.     /* this end is not reached */
  78.     return fp;    /* but keep the compiler happy (volatile functions are not ANSI) */
  79. }
  80.  
  81. void ParseDefinitionFile(void) {
  82.     FILE *fp;
  83.     int mode = 0;
  84.     char s[MAXXSOKDIRLEN+22];
  85.  
  86.     piped = 0;
  87.     maxlevel = 99;
  88.     pushcost = 10;
  89.     movecost = 1;
  90.     sprintf(s, "%s/%s/definitions", xsokdir, game.type);
  91.     if (!(fp = fopen(s, "r")))
  92.     fp = def_open(";WALLS\n");
  93.     numabbrevs = nwalls = nobjects = 0;
  94.     while (fgets(s, sizeof(s), fp)) {
  95.     int len;
  96.     len = strlen(s);
  97.     if (len && s[len-1] == '\n')
  98.         s[--len] = '\0';
  99.     if (!strcmp(s, ";WALLS")) {
  100.         mode = 0;
  101.     } else if (!strcmp(s, ";OBJECTS")) {
  102.         mode = 1;
  103.     } else if (!strncmp(s, ";MAXLEVEL", 9)) {
  104.         maxlevel = atoi(s+9);
  105.         if (maxlevel < 1 || maxlevel > 99)
  106.         maxlevel = 99;
  107.     } else if (!strncmp(s, ";PUSHCOST", 9)) {
  108.         pushcost = atoi(s+9);
  109.     } else if (!strncmp(s, ";MOVECOST", 9)) {
  110.         movecost = atoi(s+9);
  111.     } else if (!strncmp(s, ";ATOP ", 6)) {
  112.         if (numabbrevs == MAXABBREVS)
  113.         fatal("Too many abbrevs!\n");
  114.         strncpy(abbrevs[numabbrevs++], s+6, 3);
  115.     } else if (!strncmp(s, ";LEVEL", 6))
  116.         break;
  117.     if (!len || *s == ';')
  118.         continue;    /* comment or empty line */
  119.     switch (mode) {
  120.     case 0:
  121.         {   struct walls *wp;
  122.         if (nwalls == MAXWALLS)
  123.             fatal("Too many wall types\n");
  124.         wp = walls + nwalls++;
  125.         wp->chr = *s;
  126.         if (sscanf(s+1, "%x %x %x %x %d", &wp->pic, &wp->enter,
  127.                &wp->leave, &wp->mask, &wp->effect) != 5)
  128.             fatal("Bad line for character '%c':\n%s\n",
  129.               wp->chr, s);
  130.         }
  131.         break;
  132.     case 1:
  133.         {   struct objects *wp;
  134.         if (nobjects == MAXOBJECTS)
  135.             fatal("Too many object types\n");
  136.         wp = objects + nobjects++;
  137.         wp->chr = *s;
  138.         if (sscanf(s+1, "%x %x %x %d %d %x %d", &wp->pic, &wp->movedir,
  139.                &wp->pushdir, &wp->weight, &wp->power, &wp->mask,
  140.                &wp->score) != 7)
  141.             fatal("Bad line for character '%c':\n%s\n",
  142.               wp->chr, s);
  143.         }
  144.         break;
  145.     default:
  146.         ;
  147.     }
  148.     }
  149.     if (piped)
  150.     zreadclose(fp);
  151.     else
  152.     fclose(fp);
  153.     if (!nwalls || !nobjects)
  154.     fatal("Definition file is empty\n");
  155. }
  156.  
  157.  
  158. static void dfs(int x, int y) {
  159.     if (x < 0 || y < 0 || x >= game.numcols || y >= game.numrows)
  160.     return;
  161.     if (map[y][x] != walls)
  162.     return;
  163.     map[y][x] = &the_void;
  164.     dfs(x-1, y);
  165.     dfs(x, y-1);
  166.     dfs(x+1, y);
  167.     dfs(x, y+1);
  168. }
  169.  
  170. /* read current level of current game.type */
  171.  
  172. void ParseMapFile(void) {
  173.     FILE *fp;
  174.     int x, y;
  175.     struct objects *ip;
  176.     char s[MAXXSOKDIRLEN+20];
  177.  
  178.     piped = 0;
  179.     sprintf(s, "%s/%s/screen.%02d", xsokdir, game.type, game.level);
  180.     if (!(fp = fopen(s, "r"))) {
  181.     sprintf(s, ";LEVEL %d\n", game.level);
  182.     fp = def_open(s);
  183.     }
  184.     ninstances = 0;
  185.     for (x = 0; x < MAXCOL; ++x)
  186.     for (y = 0; y < MAXROW; ++y) {
  187.         map[y][x] = walls;
  188.         obj[y][x] = NULL;
  189.     }
  190.     init.level = game.level;
  191.     init.type = game.type;
  192.     *levelcomment = '\0';
  193.     *levelauthor = '\0';
  194.     game = init;
  195.     ip = instance;
  196.     for (y = 1; fgets(s, sizeof(s), fp); ++y) {
  197.     int c, cc;
  198.     /* parse s to map */
  199.     if (*s == ';') {
  200.         if (!strncmp(s+1, "LEVEL", 5))
  201.         break;
  202.         --y;    /* line doesn't count */
  203.         if (!strncmp(s+1, "COMMENT ", 8)) {
  204.         strncpy(levelcomment, s+9, sizeof(levelcomment)-1);
  205.         levelcomment[sizeof(levelcomment)-1] = '\0';
  206.         if (strchr(levelcomment, '\n'))
  207.             *strchr(levelcomment, '\n') = '\0';
  208.         }
  209.         if (!strncmp(s+1, "AUTHOR ", 7)) {
  210.         strncpy(levelauthor, s+8, sizeof(levelauthor)-1);
  211.         levelauthor[sizeof(levelauthor)-1] = '\0';
  212.         if (strchr(levelauthor, '\n'))
  213.             *strchr(levelauthor, '\n') = '\0';
  214.         }
  215.         continue;    /* skip this line (extra comment) */
  216.     }
  217.     if (y == MAXROW-1)
  218.         fatal("Level is too big\n");
  219.     for (x = 1; (c=s[x-1]) && c != '\n'; ++x) {
  220.         struct objects *op;
  221.         struct walls *wp;
  222.         int n;
  223.         if (x == MAXCOL-1)
  224.         fatal("Level is too wide\n");
  225.         if (x > game.numcols)
  226.         game.numcols = x;
  227.         /* check, if c is an abbrev */
  228.         cc = walls[0].chr;    /* make standard floor below (should be space) */
  229.         for (n = 0; n < numabbrevs; ++n)
  230.         if (abbrevs[n][0] == c) {
  231.             c = abbrevs[n][1];
  232.             cc = abbrevs[n][2];
  233.         }
  234.         for (op = objects, n = nobjects; n; --n, ++op)
  235.         if (op->chr == c) {    /* object found */
  236.             if (op == objects) {    /* player himself */
  237.             if (game.x >= 0)
  238.                 fatal("Multiple player positions\n");
  239.             game.x = x;
  240.             game.y = y;
  241.             }
  242.             if (ninstances++ == MAXINSTANCES)
  243.             fatal("Too many objects\n");
  244.             *ip = *op;    /* copy object */
  245.             ip->chr = '\0';    /* mark unmoved object */
  246.             obj[y][x] = ip++;
  247.             c = cc;        /* floor type */
  248.             break;
  249.         }
  250.         for (wp = walls, n = nwalls; n; --n, ++wp)
  251.         if (wp->chr == c) {    /* wall found */
  252.             map[y][x] = wp;
  253.             break;
  254.         }
  255.         if (!n)
  256.         fatal("No wall type found for character '%c'\n", c);
  257.     }
  258.     }
  259.     if (piped)
  260.     zreadclose(fp);
  261.     else
  262.     fclose(fp);
  263.     game.numrows = y+1;
  264.     game.numcols += 2;
  265.     /* change floor to void */
  266.     dfs(0, 0);
  267.  
  268.     /* save to orglevel for easy restart */
  269.     memcpy(omap, map, sizeof(map));
  270.     memcpy(oobj, obj, sizeof(obj));
  271.     memcpy(oinstance, instance, sizeof(instance));
  272.     game.macroStart = -1;    /* no macro available */
  273.     ogame = game;
  274.     cmd_ReadHighscores();
  275.     lastcmd = NULL;
  276. }
  277.